package com.alibaba.citrus.cr.b2b.trade.order.functions.order.entity;

import com.alibaba.citrus.cr.b2b.trade.order.facade.common.SetOrderTag;
import com.alibaba.citrus.cr.b2b.trade.order.repository.*;
import com.alibaba.citrus.cr.common.annotation.EpochTransactional;
import com.alibaba.citrus.cr.common.annotation.FunctionInvoker;
import com.alibaba.citrus.cr.common.constant.OrderFeaturesKey;
import com.alibaba.citrus.cr.common.constant.SaleOrderConstants;
import com.alibaba.citrus.cr.common.enums.GeneralStatusEnum;
import com.alibaba.citrus.cr.common.enums.ordercenter.FulfillmentStatusEnum;
import com.alibaba.citrus.cr.common.enums.ordercenter.SalesOrderStatusEnum;
import com.alibaba.citrus.cr.common.exception.FunctionException;
import com.alibaba.citrus.cr.common.log.ModuleEnum;
import com.alibaba.citrus.cr.common.util.SpringContextUtil;
import com.alibaba.cz.base.tool.Nullable;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.cz.base.tool.log.model.OpLogModel;
import com.alibaba.cz.base.tool.log.model.OperatorType;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.db.service.CustomSequenceAccessor;
import com.alibaba.lattice2.epoch.middleware.mq.runtime.EpochMessageService;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcorder.contants.BcOrderConstants;
import com.epoch.app.bcorder.esdegrade.dto.GetEsDegradeValueResponse;
import com.epoch.app.bcorder.esdegrade.service.EsDegradeService;
import com.epoch.app.bcorder.model.dto.EmployeeGetCurrentLoginResponse;
import com.epoch.app.bcorder.model.dto.SearchCargoZoneListByDBRequest;
import com.epoch.app.bcorder.model.dto.SearchCargoZoneListByDBResponse;
import com.epoch.app.bcorder.model.dto.WarehouseInfo;
import com.epoch.app.bcorder.platform_enhance.SaleOrderTag;
import com.epoch.app.bcorder.service.UnifiedInventoryService;
import com.epoch.app.crb2btradecenter.dto.response.BatchCreateOrderResponse;
import com.epoch.app.crb2btradecenter.enums.OrderStatus;
import com.epoch.app.crb2btradecenter.messagetask.dto.CreateResponse;
import com.epoch.app.crb2btradecenter.messagetask.model.MessageTask;
import com.epoch.app.crb2btradecenter.messagetask.service.MessageTaskService;
import com.epoch.app.crb2btradecenter.model.dto.TradeMessageSDO;
import com.epoch.app.crb2btradecenter.model.enums.MessageTaskTypeEnum;
import com.epoch.app.crb2btradecenter.model.enums.OrderOperateType;
import com.epoch.app.crb2btradecenter.sdo.OrderLineSDO;
import com.epoch.app.crb2btradecenter.sdo.OrderSDO;
import com.epoch.app.crplatformenhance.api.strategyquery.service.StrategyQueryService;
import com.epoch.app.crplatformenhance.enums.DimensionTypeEnum;
import com.epoch.app.crplatformenhance.enums.StrategyTypeEnum;
import com.epoch.app.crplatformenhance.model.dto.StrategyPageQueryRequest;
import com.epoch.app.crplatformenhance.model.dto.StrategyPageQueryResponse;
import com.epoch.app.crplatformenhance.model.dto.StrategyQueryByIdRequest;
import com.epoch.app.crplatformenhance.model.dto.StrategyQueryByIdResponse;
import com.epoch.app.crplatformenhance.sdo.DimensionSDO;
import com.epoch.app.crpricecenter.api.creditquery.service.CreditQueryService;
import com.epoch.app.crunifiedinventory.model.dto.ForecastAnalysisInventoryRequest;
import com.epoch.app.crunifiedinventory.model.dto.ForecastAnalysisQueryInventoryRequest;
import com.epoch.app.crunifiedinventory.model.dto.GetListWarehouseStockRequest;
import com.epoch.app.crunifiedinventory.model.dto.WarehouseInventory;
import com.epoch.app.crunifiedinventory.service.CrUnifiedInventoryService;
import com.google.common.collect.Lists;
import lombok.Getter;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;


@Getter
public class OrderWriteEntity {
    private static final Log log = Log.getLogger(OrderWriteEntity.class);

    private static final String TYPE = "1";

    private static final String FIXED_VALUE = "10";

    private static final String RETURN_FLAG = "1";
    private static OrderWriteRepository orderWriteRepository;
    private static OrderLineWriteRepository orderLineWriteRepository;
    private static EpochMessageService messageService;
    private static DeliverOrderWriteRepository deliverOrderWriteRepository;
    private static DeliveryOrderDetailRepository deliveryOrderDetailRepository;
    //    private static CreditRepository creditRepository;
    private static CreditQueryService creditQueryService;
    private static CrUnifiedInventoryService crUnifiedInventoryService;
    private static OrderQueryServiceRepository orderQueryServiceRepository;
    private static CustomSequenceAccessor customSequenceAccessor;
    private static OrderBackUpRepository orderBackUpRepository;
    private static EsDegradeService esDegradeService;
    private static StrategyQueryService strategyQueryService;
    private static MessageTaskService messageTaskService;
    private static UnifiedInventoryService unifiedInventoryService;

    private OrderSDO orderSDO;

    static {
        customSequenceAccessor = SpringContextUtil.getBean(CustomSequenceAccessor.class);
        orderWriteRepository = SpringContextUtil.getBean(OrderWriteRepository.class);
        orderLineWriteRepository = SpringContextUtil.getBean(OrderLineWriteRepository.class);
        messageService = SpringContextUtil.getBean(EpochMessageService.class);
        deliverOrderWriteRepository = SpringContextUtil.getBean(DeliverOrderWriteRepository.class);
        deliveryOrderDetailRepository = SpringContextUtil.getBean(DeliveryOrderDetailRepository.class);
        creditQueryService = SpringContextUtil.getBean(CreditQueryService.class);
        crUnifiedInventoryService = SpringContextUtil.getBean(CrUnifiedInventoryService.class);
        orderQueryServiceRepository = SpringContextUtil.getBean(OrderQueryServiceRepository.class);
        orderBackUpRepository = SpringContextUtil.getBean(OrderBackUpRepository.class);
        esDegradeService = SpringContextUtil.getBean(EsDegradeService.class);
        strategyQueryService = SpringContextUtil.getBean(StrategyQueryService.class);
        messageTaskService = SpringContextUtil.getBean(MessageTaskService.class);
        unifiedInventoryService = SpringContextUtil.getBean(UnifiedInventoryService.class);
    }

    public static OrderWriteEntity of(OrderSDO orderSDO) {
        OrderWriteEntity orderWriteEntity = new OrderWriteEntity();
        orderWriteEntity.orderSDO = orderSDO;
        return orderWriteEntity;
    }

    @FunctionInvoker
    public static Result checkStockAndCredit(OrderSDO orderSDO) {
        Map<String, String> features = orderSDO.getFeatures();
        //库存范围精度
        BigDecimal precisionRange = BigDecimal.ZERO;
        //退货订单不进行库存和信贷校验
        if (SetOrderTag.RETURN.equals(orderSDO.getOrderTag()) || (features != null && features.get(SaleOrderConstants.PUSH_COUNT) != null)) {
            return Result.success(null);
        }
        //add by myw at 20230210 for 预报单转换的销售单库存不校验配置 end
        if (StringUtils.isNotBlank(orderSDO.getFrontOrderId())) {
            String organizationCode = orderSDO.getOrganizationCode();
            StrategyPageQueryRequest moreConditionQueryRequest = new StrategyPageQueryRequest();
            moreConditionQueryRequest.setType(StrategyTypeEnum.INVENTORY_VALID.getCode());
            moreConditionQueryRequest.setOrganizationCode(organizationCode);
            try {
                Result<List<StrategyPageQueryResponse>> moreConditionQueryResponseResult = strategyQueryService.pageQuery(moreConditionQueryRequest);
                if (Objects.nonNull(moreConditionQueryResponseResult)
                        && CollectionUtils.isNotEmpty(moreConditionQueryResponseResult.getResult())) {
                    log.info("销售订单确认库存校验，销售单:{},命中库存不检查策略:{},跳过库存校验", orderSDO.getOrderBizId(), moreConditionQueryResponseResult.getResult().get(0).getStrategyName());
                    return Result.success(null);
                }
            } catch (Throwable e) {
                log.error("销售订单确认库存校验，销售单:{},查询库存不检查策略异常:{},", orderSDO.getOrderBizId(), e);
                e.printStackTrace();

            }


            //add by myw,at 20230228 for 库存补差配置 end
            StrategyPageQueryRequest strategyPageQueryRequest = new StrategyPageQueryRequest();
            strategyPageQueryRequest.setOrganizationCode(organizationCode);
            strategyPageQueryRequest.setStatus(1);//有效的策略
            strategyPageQueryRequest.setType(StrategyTypeEnum.INVENTORY_RANGE.getCode());//查询优先回复策略
            log.info("查询库存补差入参" + JSONObject.toJSONString(strategyPageQueryRequest));
            try {

                Result<List<StrategyPageQueryResponse>> listResult = strategyQueryService.pageQuery(strategyPageQueryRequest);
                log.info("查询库存补差出参" + JSONObject.toJSONString(listResult));
                if (Objects.nonNull(listResult) && CollectionUtils.isNotEmpty(listResult.getResult())) {
                    //查询组织策略详情
                    StrategyQueryByIdRequest channelRequest = new StrategyQueryByIdRequest();
                    channelRequest.setId(listResult.getResult().get(0).getId());
                    channelRequest.setStatus("0");
                    channelRequest.setCode(DimensionTypeEnum.ORGANIZE.getCode());
                    log.info("查询库存补差详情入参" + JSONObject.toJSONString(channelRequest));
                    Result<StrategyQueryByIdResponse> channelResponseResult = strategyQueryService.queryById(channelRequest);
                    log.info("查询库存补差详情出参" + JSONObject.toJSONString(channelResponseResult));
                    if (Objects.nonNull(channelResponseResult.getResult())
                            && Objects.nonNull(channelResponseResult.getResult().getStrategySDO())) {
                        List<DimensionSDO> dimensionSDOS = channelResponseResult.getResult().getStrategySDO().getDimensionSDOList();
                        if (CollectionUtils.isEmpty(dimensionSDOS)) {
                            log.warn("查询库存补差策略详情维度为空");
                        }
                        for (DimensionSDO dimensionSDO : dimensionSDOS) {
                            //主单ID-库存精度范围
                            String value = dimensionSDO.getValue();
                            if (StringUtils.isNotBlank(value) && dimensionSDO.getStatus().equals("0")) {
                                long startTime = dimensionSDO.getValidBeginTime().getTime();
                                long endTime = dimensionSDO.getValidEndTime().getTime();
                                long nowTime = new Date().getTime();
                                if (startTime <= nowTime && nowTime <= endTime) {
                                    precisionRange = new BigDecimal(value).divide(BigDecimal.valueOf(100), 3, RoundingMode.HALF_UP);
                                    break;
                                }
                            }
                        }
                    }
                    log.info("销售订单确认库存校验，销售单:{},命中库存补差策略:{},补差值{}", orderSDO.getOrderBizId(), listResult.getResult().get(0).getStrategyName(), precisionRange);
                }
            } catch (Throwable e) {
                log.error("预报订单确认库存校验，销售单:{},查询库存补差策略异常,{}", orderSDO.getOrderBizId(), e);
                e.printStackTrace();
            }
        }
        //校验库存
        GetListWarehouseStockRequest getRequest = new GetListWarehouseStockRequest();
        getRequest.setWarehouseAreaId(orderSDO.getWareHouseCode());
        getRequest.setType("1");
        for (OrderLineSDO orderLineSDO : orderSDO.getOrderLineSDOS()) {
            String scItemId = orderLineSDO.getScItemSDO().getScItemId();
            //销售数量
            BigDecimal quantity = new BigDecimal(orderLineSDO.getScItemSDO().getQuantity());
            //库存数量
            BigDecimal availableQuantityBigDecimal = new BigDecimal(0);
            //支持es降级查询db
            GetEsDegradeValueResponse degradeValueResponse = esDegradeService.getEsDegradeValue();
            if (Objects.nonNull(degradeValueResponse) && degradeValueResponse.getResult()) {
                ForecastAnalysisQueryInventoryRequest queryAvailableInventoryRequest = new ForecastAnalysisQueryInventoryRequest();
                queryAvailableInventoryRequest.setWarehouseAreaId(orderSDO.getWareHouseCode());
                queryAvailableInventoryRequest.setTypes(Lists.newArrayList(2, 3));
                queryAvailableInventoryRequest.setGoodsId(scItemId);
                Result<List<ForecastAnalysisInventoryRequest>> queryInventoryResponse = crUnifiedInventoryService.forecastAnalysisQueryInventory(queryAvailableInventoryRequest);
                if (CollectionUtils.isEmpty(queryInventoryResponse.getResult())) {
                    return Result.fail(null, "仓库中未查到对应货品的库存数据");
                }
                ForecastAnalysisInventoryRequest warehouseInventory = queryInventoryResponse.getResult().get(0);
                if (null == warehouseInventory.getAvailableQuantity()) {
                    return Result.fail(null, "库存不足");
                }
                availableQuantityBigDecimal = new BigDecimal(warehouseInventory.getAvailableQuantity());
            } else {
                getRequest.setGoodsId(scItemId);
                Result<List<WarehouseInventory>> listWarehouseStock = crUnifiedInventoryService.getListWarehouseStock(getRequest);
                if (CollectionUtils.isEmpty(listWarehouseStock.getResult())) {
                    return Result.fail(null, "仓库中未查到对应货品的库存数据");
                }
                WarehouseInventory warehouseInventory = listWarehouseStock.getResult().get(0);
                if (null == warehouseInventory.getAvailableQuantityFormat()) {
                    return Result.fail(null, "库存不足");
                }
                availableQuantityBigDecimal = new BigDecimal(warehouseInventory.getAvailableQuantityFormat());
            }

            if (StringUtils.isBlank(orderLineSDO.getScItemSDO().getUnitConvert())) {
                log.error("库存不足 订单数量 = {}", quantity);
                log.error("商品：{}", JSONObject.toJSON(orderLineSDO.getScItemSDO()));
                return Result.fail(null, "该商品没有单位转换关系");
            }
            BigDecimal quantityOfInventory = quantity.divide(new BigDecimal(orderLineSDO.getScItemSDO().getUnitConvert()), 3, RoundingMode.HALF_UP);
            //考虑库存补差后的库存
            BigDecimal afterRangeInventory = availableQuantityBigDecimal.multiply(BigDecimal.ONE.add(precisionRange)).setScale(3, RoundingMode.HALF_UP);
            if (quantityOfInventory.compareTo(afterRangeInventory) > 0) {
                log.error("库存不足 订单数量 = {}", quantity);
                log.error("库存不足 库存数量 = {}", availableQuantityBigDecimal);
                return Result.fail(null, "库存不足");
            }
        }
        return Result.success(null);
    }

    /**
     * 保存销售订单
     * 预报单生成调用
     *
     * @return
     * @param employeeGetCurrentLoginResponse
     */
    @FunctionInvoker
    public List<BatchCreateOrderResponse> batchSave(EmployeeGetCurrentLoginResponse employeeGetCurrentLoginResponse) {
        try {
            Integer num = 0;
            //存在sap单号无需校验直接创建订单
            log.info("OrderWriteEntity#batchSave outOrderId:{}; orderSDO:{}", orderSDO.getOuterOrderId(), JSON.toJSONString(orderSDO));
            if (StringUtils.isNotBlank(orderSDO.getOuterOrderId())) {
                //保存销售订单主单，方法里面进行sdo转do
                String orderId = orderWriteRepository.saveOrder(orderSDO);
                orderSDO.setId(orderId);
                printOperateLog(orderSDO,employeeGetCurrentLoginResponse,OrderOperateType.CREATE);
                if (SetOrderTag.EXCHANGE.equals(orderSDO.getOrderTag())) {
                    //换货集合
                    List<OrderLineSDO> exchangeList = new ArrayList<>();
                    //退货集合
                    List<OrderLineSDO> returnList = new ArrayList<>();
                    if (CollectionUtils.isEmpty(orderSDO.getOrderLineSDOS())) {
                        throw new FunctionException("OTS-05-001-10-16-039");
                    }
                    for (OrderLineSDO orderLineSDO : orderSDO.getOrderLineSDOS()) {
                        if (StringUtils.isNotBlank(orderLineSDO.getReturnCharacter()) && RETURN_FLAG.equals(orderLineSDO.getReturnCharacter())) {
                            returnList.add(orderLineSDO);
                        } else {
                            exchangeList.add(orderLineSDO);
                        }
                    }
                    if (CollectionUtils.isEmpty(exchangeList)) {
                        throw new FunctionException("OTS-05-001-10-16-037");
                    }

                    for (OrderLineSDO orderLineSDO : exchangeList) {
                        num = ++num * Integer.parseInt(FIXED_VALUE);
                        orderLineSDO.setMainOrderId(orderId);
                        orderLineSDO.setSyncVersion(0);
                        orderLineSDO.setMainOrderBizId(orderSDO.getOrderBizId());
                        orderLineSDO.setSerialNumber(String.valueOf(num));
                        orderLineSDO.setOrderLineTag(SetOrderTag.EXCHANGE);
                        num = num / Integer.parseInt(FIXED_VALUE);
                    }
                    Map<String, OrderLineSDO> orderLineSDOMap = exchangeList.stream().collect(Collectors.toMap(orderLineSDO -> orderLineSDO.getScItemSDO().getScItemOutCode(), o -> o));

                    if (CollectionUtils.isEmpty(returnList)) {
                        throw new FunctionException("OTS-05-001-10-16-038");
                    }
                    List<OrderLineSDO> orderLineSDOS = new ArrayList<>();

                    for (OrderLineSDO orderLineSDO : returnList) {
                        if (Objects.nonNull(orderLineSDO.getScItemSDO()) && StringUtils.isNotBlank(orderLineSDO.getScItemSDO().getScItemOutCode())) {
                            OrderLineSDO orderLineSDO1 = orderLineSDOMap.get(orderLineSDO.getScItemSDO().getScItemOutCode());
                            orderLineSDOS.add(orderLineSDO1);
                            if (Objects.nonNull(orderLineSDO1)) {
                                orderLineSDO.setMainOrderId(orderId);
                                orderLineSDO.setSyncVersion(0);
                                orderLineSDO.setSerialNumber((Integer.parseInt(orderLineSDO1.getSerialNumber()) + 1) + "");
                                orderLineSDO.setMainOrderBizId(orderSDO.getOrderBizId());
                                orderLineSDO.setOrderLineTag(SetOrderTag.RETURN);
                                orderLineSDOS.add(orderLineSDO);
                            }
                        }
                    }
                    if (CollectionUtils.isNotEmpty(orderLineSDOS)) {
                        for (OrderLineSDO orderLineSDO : orderLineSDOS) {
                            String s = orderLineWriteRepository.batchCreateOrderLine(orderLineSDO);
                            orderLineSDO.setId(s);
                        }
                    }
                } else {
                    for (OrderLineSDO orderLineSDO : orderSDO.getOrderLineSDOS()) {
                        num = ++num * Integer.parseInt(FIXED_VALUE);
                        orderLineSDO.setMainOrderId(orderId);
                        orderLineSDO.setSyncVersion(0);
                        orderLineSDO.setMainOrderBizId(orderSDO.getOrderBizId());
                        orderLineSDO.setSerialNumber(String.valueOf(num));
                        Map<String, String> features = orderLineSDO.getFeatures();
                        SearchCargoZoneListByDBRequest searchCargoZoneListByDBRequest = new SearchCargoZoneListByDBRequest();
                        searchCargoZoneListByDBRequest.setStart(0);
                        searchCargoZoneListByDBRequest.setLimit(1);
                        searchCargoZoneListByDBRequest.setStatus(1);
                        searchCargoZoneListByDBRequest.setCode(orderLineSDO.getShippingWarehouseOutCode());
                        searchCargoZoneListByDBRequest.setSapFactoryCode(orderLineSDO.getDeliveryFactoryCode());
                        searchCargoZoneListByDBRequest.setWarehouseCode(orderLineSDO.getStockCode());
                        SearchCargoZoneListByDBResponse searchCargoZoneListByDBResponse = unifiedInventoryService.searchCargoZoneListByDB(searchCargoZoneListByDBRequest);
                        log.info("OrderWriteEntity#batchSave searchCargoZoneListByDBRequest:{}; searchCargoZoneListByDBResponse:{}", JSON.toJSONString(searchCargoZoneListByDBRequest), JSON.toJSONString(searchCargoZoneListByDBResponse));
                        if (searchCargoZoneListByDBResponse.getSuccess()) {
                            List<WarehouseInfo> warehouseInfoList = searchCargoZoneListByDBResponse.getResult();
                            WarehouseInfo warehouseInfo = warehouseInfoList.get(0);
                            if (Objects.nonNull(warehouseInfo) && !Objects.equals(5, warehouseInfo.getType())) {
                                if (SalesOrderStatusEnum.BEFORE_DELIVERY.equals(SalesOrderStatusEnum.of(orderLineSDO.getStatus()))) {
                                    if (StringUtils.isBlank(features.get(OrderFeaturesKey.FULFILLMENT_STATUS)) || FulfillmentStatusEnum.FAIL_FULFILLMENT.equals(FulfillmentStatusEnum.of(features.get(OrderFeaturesKey.FULFILLMENT_STATUS)))) {
                                        features.put(OrderFeaturesKey.FULFILLMENT_STATUS, FulfillmentStatusEnum.BEFORE_FULFILLMENT.getCode());
                                    }
                                } else if (SalesOrderStatusEnum.STAY_PUSH.equals(SalesOrderStatusEnum.of(orderLineSDO.getStatus())) || SalesOrderStatusEnum.PUSHING.equals(SalesOrderStatusEnum.of(orderLineSDO.getStatus()))){
                                    features.put(OrderFeaturesKey.FULFILLMENT_STATUS, FulfillmentStatusEnum.FAIL_FULFILLMENT.getCode());
                                }
                                orderLineSDO.setFeatures(features);
                            }
                        }
                        //保存销售订单明细，方法里面进行sdo转do
                        log.info("OrderWriteEntity#batchSave orderLineSDO:{}", JSON.toJSONString(orderLineSDO));
                        String s = orderLineWriteRepository.batchCreateOrderLine(orderLineSDO);
                        orderLineSDO.setId(s);
                        num = num / Integer.parseInt(FIXED_VALUE);
                    }
                }
                List<BatchCreateOrderResponse> responses = new ArrayList<>();
                BatchCreateOrderResponse response = new BatchCreateOrderResponse();
                response.setOrderId(orderId);


                // sap发送订单创建消息
                TradeMessageSDO tradeMessageSDO = new TradeMessageSDO();
                tradeMessageSDO.setOrderSDO(orderSDO);
                String message = JSON.toJSONString(tradeMessageSDO);
                Map<String, String> map = new HashMap<>();
                map.put("_CZ_KEY", BcOrderConstants.TENANT_ID());
                log.info("SaleOrderSapCreated orderId = " + orderSDO.getId() + ", message = " + message + ",map = " + JSON.toJSONString(map) + " start");
                messageService.sendMessage("sale_order_message", "CR_SALEORDER_V2", "SaleOrderSapCreated", orderSDO.getOrderBizId(), message, map);
                log.info("SaleOrderSapCreated order message = " + message + "end");
                response.setTradeMessageSDO(tradeMessageSDO);
                responses.add(response);
                return responses;
            }

            if (orderSDO.getOrderBizId() == null) {
                String nextStringSequence = customSequenceAccessor.getNextStringSequence("cr_b2b_trade_center", "saleOrderSequence");
                orderSDO.setOrderBizId(nextStringSequence);
            }
            Result flag = checkStockAndCredit(orderSDO);
            Date date = new Date();
            Map<String, String> features = orderSDO.getFeatures();
            if (MapUtils.isEmpty(features)) {
                features = new HashMap<>();
            }
//            BatchCreateOrderResponse response = new BatchCreateOrderResponse();

            this.orderSDO.setStatus(OrderStatus.PUSHING.getCode());

//            features.put(SaleOrderConstants.EXT_MESSAGE, flag.getMessage());
            if (!flag.isSuccess()) {
                this.orderSDO.setStatus(OrderStatus.STAY_PUSH.getCode());
                features.put(SaleOrderConstants.EXT_MESSAGE, flag.getMessage());
            }

            this.orderSDO.setFeatures(features);
            this.orderSDO.setSyncVersion(0);
            // TODO 暂时固定值  等预报传
            this.orderSDO.setOrderTag(orderSDO.getOrderTag() == null ? "normal" : orderSDO.getOrderTag());
            orderSDO.setGmtCreate(date);
            orderSDO.setGmtModified(date);
            String orderId = orderWriteRepository.saveOrder(this.orderSDO);
            orderSDO.setId(orderId);
            printOperateLog(orderSDO,employeeGetCurrentLoginResponse,OrderOperateType.CREATE);
//            orderSDO.setId(orderId);
            String forecastOrderId = "";
            Integer quantityList = 0;
            List<BatchCreateOrderResponse> batchCreateOrderResponses = new ArrayList<>();
            log.info("orderSDO.getOrderLineSDOS大小:{}", orderSDO.getOrderLineSDOS().size());
            for (OrderLineSDO orderLineSDO : orderSDO.getOrderLineSDOS()) {
                //num = ++num * Integer.parseInt(FIXED_VALUE);
                orderLineSDO.setMainOrderId(orderId);
                orderLineSDO.setSyncVersion(0);
                orderLineSDO.setMainOrderBizId(orderSDO.getOrderBizId());
                // TODO 暂时固定值  等预报传
                orderLineSDO.setOrderLineTag(SetOrderTag.NORMAL);
                orderLineSDO.setGmtCreate(date);
                orderLineSDO.setGmtModified(date);
                //orderLineSDO.setSerialNumber(String.valueOf(num));
                String orderLineId = orderLineWriteRepository.batchCreateOrderLine(orderLineSDO);
                orderLineSDO.setId(orderLineId);
                forecastOrderId = orderLineSDO.getFrontOrderLineId();
                quantityList = orderLineSDO.getScItemSDO().getQuantity();
                Map<String, String> featuresLine = orderLineSDO.getFeatures();
                //不是赠品的信息 返回预报信息  更新预报状态
                if (!(MapUtils.isNotEmpty(featuresLine) && ("gift").equals(String.valueOf(featuresLine.get("giftFlag"))))) {
                    BatchCreateOrderResponse response = new BatchCreateOrderResponse();
                    response.setOrderId(orderId);
                    response.setOrderBizId(orderSDO.getOrderBizId());
                    response.setForecastOrderLineId(forecastOrderId);
                    response.setPredictReplyAmount(quantityList);
                    response.setMessage(flag.getMessage());
                    //num = num / Integer.parseInt(FIXED_VALUE);
                    batchCreateOrderResponses.add(response);
                }
            }

            TradeMessageSDO tradeMessageSDO = new TradeMessageSDO();
            tradeMessageSDO.setOrderSDO(orderSDO);
            String message = JSON.toJSONString(tradeMessageSDO);
            Map<String, String> map = new HashMap<>();
            map.put("_CZ_KEY", "mengniu");
            log.info("orderId = " + orderSDO.getId() + ", message = " + message + ",map = " + JSON.toJSONString(map) + " start");
            if (flag.isSuccess()) {
                messageService.sendMessage("sale_order_message", "CR_SALEORDER_V2", "SaleCreated", orderSDO.getOrderBizId(), message, map);
            }
            log.info("batchSave order message = " + message + "end");
            Nullable.stream(batchCreateOrderResponses).forEach(o -> o.setTradeMessageSDO(tradeMessageSDO));
            log.info("batchCreateOrderResponses结果:{}",JSON.toJSONString(batchCreateOrderResponses));
            log.info("batchCreateOrderResponses大小:{}",batchCreateOrderResponses.size());
            return batchCreateOrderResponses;
        } catch (Exception e) {
            log.error("batchSave order exception ", e);
            throw new FunctionException(e.getMessage());
        }
    }

    private void printOperateLog(OrderSDO orderSDO,EmployeeGetCurrentLoginResponse employeeGetCurrentLoginResponse,OrderOperateType orderOperateType){

        OpLogModel.OpLogModelBuilder<String> builder = OpLogModel.builder();
        OpLogModel<String> opLogModel = builder.build();
        opLogModel.setModuleName(ModuleEnum.SALES.getModuleName());
        opLogModel.setModuleId(String.valueOf(ModuleEnum.SALES.getModuleId()));
        opLogModel.setObjectId(orderSDO.getId());
        opLogModel.setObjectName("so_order_id");
        opLogModel.setOperateType(orderOperateType.getCode());
        opLogModel.setOperatorType(OperatorType.USER.getOperatorType());
        Map<String, String> map = new HashMap<>();
        if (org.apache.commons.lang.StringUtils.isNotBlank(employeeGetCurrentLoginResponse.getEmployeeId()) && org.apache.commons.lang.StringUtils.isNotBlank(employeeGetCurrentLoginResponse.getEmployeeName())) {
            opLogModel.setOperatorId(employeeGetCurrentLoginResponse.getEmployeeId());
            map.put("name", employeeGetCurrentLoginResponse.getEmployeeName());
        }
        map.put("active", orderOperateType.getDesc());
        map.put("bizNo", orderSDO.getOrderBizId());
        if (StringUtils.isNotBlank(orderSDO.getOrderType())){
            SaleOrderTag saleOrderTag = SaleOrderTag.of(orderSDO.getOrderType());
            if (Objects.nonNull(saleOrderTag)){
                map.put("orderType",saleOrderTag.getDesc());
            }
        }
        if (Objects.nonNull(orderSDO.getStatus())){
            OrderStatus orderStatus = OrderStatus.of(orderSDO.getStatus());
            if (Objects.nonNull(orderStatus)){
                map.put("status",orderStatus.getDesc());
            }
        }
        String logInfo = JSONObject.toJSONString(map);
        opLogModel.setFeatures(logInfo);
        log.asyncMonitorObjectChangeV2(opLogModel);
    }
    /**
     * 页面提交操作
     *
     * @return
     */
    @EpochTransactional(appCode = "cr_b2b_trade_center", dataSourceCode = "cr_ots", dataSourceType = "app")
    public Result<Boolean> submit() {

//        String sequenceNo="BSD"+new Date().getTime();
        String sequenceNo = customSequenceAccessor.getNextStringSequence("cr_b2b_trade_center", "batchCreateOrderSequence");
        String taskId = startTask(sequenceNo, MessageTaskTypeEnum.ORDER_SUBMIT);
        Result flag = checkStockAndCredit(orderSDO);
        Map<String, String> features = orderSDO.getFeatures();
        if (MapUtils.isEmpty(features)) {
            features = new HashMap<>();
        }

        if (this.orderSDO.getStatus() != 2) {
            this.orderSDO.setStatus(OrderStatus.BEFORE_SUBMIT.getCode());
        }
        this.orderSDO.setStatus(OrderStatus.PUSHING.getCode());

        features.put(SaleOrderConstants.EXT_MESSAGE, flag.getMessage());
        if (!flag.isSuccess()) {
            if ("006".equals(flag.getErrorCode())) {
                // 信用贷校验不通过 改为待推送状态
                this.orderSDO.setStatus(OrderStatus.STAY_PUSH.getCode());
                orderSDO.setFeatures(features);
                orderWriteRepository.updateOrder(orderSDO);
            }
            return Result.fail("006", flag.getMessage());
        }
        orderSDO.setFeatures(features);
        orderWriteRepository.updateOrder(orderSDO);

        boolean returnFlag = false;
//        Integer num = 0;
        List<OrderLineSDO> copyList = new ArrayList<>();
        for (OrderLineSDO orderLineSDO : orderSDO.getOrderLineSDOS()) {
            orderLineSDO.setStatus(OrderStatus.PUSHING.getCode());
            //换货订单
            if ("exchange".equals(orderLineSDO.getOrderLineTag()) && orderSDO.getOrderTag().equals("exchange")) {
                OrderLineSDO copy = new OrderLineSDO();
                BeanUtils.copyProperties(orderLineSDO, copy);
                copy.setId(null);
                copy.setOrderLineTag("return");
                copy.setSerialNumber((Integer.parseInt(orderLineSDO.getSerialNumber()) + 1) + "");
                copyList.add(copy);
            }
            if ("return".equals(orderLineSDO.getOrderLineTag())) {
                returnFlag = true;
            }
            orderLineWriteRepository.modifyOrderLine(orderLineSDO);
        }

        if (CollectionUtils.isNotEmpty(copyList) && !returnFlag) {
            for (OrderLineSDO orderLineSDO : copyList) {
//                orderLineSDO.setSerialNumber(String.valueOf((++num)));
                String lineId = orderLineWriteRepository.batchCreateOrderLine(orderLineSDO);
                orderLineSDO.setId(lineId);
            }
            orderSDO.getOrderLineSDOS().addAll(copyList);
        }

        TradeMessageSDO tradeMessageSDO = new TradeMessageSDO();
        tradeMessageSDO.setOrderSDO(orderSDO);
        updateTask(Lists.newArrayList(tradeMessageSDO), taskId);

        String message = JSON.toJSONString(tradeMessageSDO);

        log.info("orderId = " + orderSDO.getId() + ", batchMessage = " + sequenceNo + " start");
        if (flag.isSuccess()) {
            sendInventoryAndIntegratedMessage(sequenceNo, message);
        }
        return Result.success(true);
    }

    /**
     * 页面提交操作
     *
     * @return
     */
    @EpochTransactional(appCode = "cr_b2b_trade_center", dataSourceCode = "cr_ots", dataSourceType = "app")
    public Result<TradeMessageSDO> submitOrderStatusSave() {

        Result flag = checkStockAndCredit(orderSDO);
        Map<String, String> features = orderSDO.getFeatures();
        if (MapUtils.isEmpty(features)) {
            features = new HashMap<>();
        }

        if (this.orderSDO.getStatus() != 2) {
            this.orderSDO.setStatus(OrderStatus.BEFORE_SUBMIT.getCode());
        }
        this.orderSDO.setStatus(OrderStatus.PUSHING.getCode());

        features.put(SaleOrderConstants.EXT_MESSAGE, flag.getMessage());
        if (!flag.isSuccess()) {
            if ("006".equals(flag.getErrorCode())) {
                // 信用贷校验不通过 改为待推送状态
                this.orderSDO.setStatus(OrderStatus.STAY_PUSH.getCode());
                orderSDO.setFeatures(features);
                orderWriteRepository.updateOrder(orderSDO);
            }
            return Result.fail("006", flag.getMessage());
        }
        orderSDO.setFeatures(features);
        orderWriteRepository.updateOrder(orderSDO);

        boolean returnFlag = false;
//        Integer num = 0;
        List<OrderLineSDO> copyList = new ArrayList<>();
        for (OrderLineSDO orderLineSDO : orderSDO.getOrderLineSDOS()) {
            orderLineSDO.setStatus(OrderStatus.PUSHING.getCode());
            //换货订单
            if ("exchange".equals(orderLineSDO.getOrderLineTag()) && orderSDO.getOrderTag().equals("exchange")) {
                OrderLineSDO copy = new OrderLineSDO();
                BeanUtils.copyProperties(orderLineSDO, copy);
                copy.setId(null);
                copy.setOrderLineTag("return");
                copy.setSerialNumber((Integer.parseInt(orderLineSDO.getSerialNumber()) + 1) + "");
                copyList.add(copy);
            }
            if ("return".equals(orderLineSDO.getOrderLineTag())) {
                returnFlag = true;
            }
            orderLineWriteRepository.modifyOrderLine(orderLineSDO);
        }

        if (CollectionUtils.isNotEmpty(copyList) && !returnFlag) {
            for (OrderLineSDO orderLineSDO : copyList) {
                String lineId = orderLineWriteRepository.batchCreateOrderLine(orderLineSDO);
                orderLineSDO.setId(lineId);
            }
            orderSDO.getOrderLineSDOS().addAll(copyList);
        }
        TradeMessageSDO tradeMessageSDO = new TradeMessageSDO();
        tradeMessageSDO.setOrderSDO(orderSDO);
        String message = JSON.toJSONString(tradeMessageSDO);
        if (flag.isSuccess()) {
            Result<Boolean> sendMessageResp = sendInventoryAndIntegratedMessage(null, message);
            if (!sendMessageResp.isSuccess()) {
                return Result.fail(sendMessageResp.getErrorCode(), sendMessageResp.getMessage());
            }
        }
        return Result.success(tradeMessageSDO);
    }

    @NotNull
    private String startTask(String sequenceNo, MessageTaskTypeEnum taskTypeEnum) {
        MessageTask messageTask = new MessageTask();
        messageTask.setBatchNo(sequenceNo);
        messageTask.setStatus(1);
        messageTask.setType(taskTypeEnum.getValue());
        messageTask.setGmt_create(new Date());
        messageTask.setGmt_modified(new Date());
        CreateResponse createResponse = messageTaskService.create(messageTask);
        return createResponse.getId();
    }

    private void updateTask(List<TradeMessageSDO> integratedOrderList, String taskId) {
        //生成销售单对象
        Map<String, List<String>> confirmOrderMap = integratedOrderList.stream().map(TradeMessageSDO::getOrderSDO).collect(Collectors.toMap(OrderSDO::getId, p -> p.getOrderLineSDOS().stream().map(OrderLineSDO::getId).collect(Collectors.toList()), (v1, v2) -> v1));
        //生成销售单对象子单总条数
        AtomicInteger orderSizeAtomic = new AtomicInteger(0);
        confirmOrderMap.values().forEach(o -> orderSizeAtomic.getAndAdd(o.size()));

        MessageTask messageTask = new MessageTask();
        messageTask.setTaskId(Long.valueOf(taskId));
        messageTask.setExtraContent(JSON.toJSONString(confirmOrderMap));
        messageTask.setExtraCount(orderSizeAtomic.get());
        messageTask.setGmt_modified(new Date());
        messageTaskService.update(messageTask);
    }

    private Result<Boolean> sendInventoryAndIntegratedMessage(String batchMessage, String message) {
        try {
            Map<String, String> map = new HashMap<>();
            map.put("_CZ_KEY", "mengniu");
            if (StringUtils.isNotBlank(batchMessage)) {
                Boolean batchSendResp = messageService.sendMessage("sale_order_message", "CR_SALEORDER_V2", "SaleBatchCreated", orderSDO.getOrderBizId(), batchMessage, map);
                if (!batchSendResp) {
                    log.error("OrderWriteEntity_Batch_submitMQ_fail");
                    return Result.fail(Boolean.FALSE, "", "OrderWriteEntity_Batch_submitMQ_fail");
                }
            }
            if (StringUtils.isNotBlank(message)) {
                Boolean sendResp = messageService.sendMessage("sale_order_message", "CR_SALEORDER_V2", "SaleCreated", orderSDO.getOrderBizId(), message, map);
                log.info("sendInventoryAndIntegratedMessage, Resp={}, message={}, map:{}", sendResp, message,map);
                if (!sendResp) {
                    log.error("OrderWriteEntity_submitMQ_fail");
                    return Result.fail(Boolean.FALSE, "", "OrderWriteEntity_submitMQ_fail");
                }
            }
            log.info("submit order batchMessage = " + batchMessage);
            log.info("submit order message = " + message);

        } catch (Throwable e) {
            log.error("sendInventoryAndIntegratedMessage exception,", e);
            e.printStackTrace();
            return Result.fail(Boolean.FALSE, "", e.getMessage());
        }
        return Result.success(Boolean.TRUE);
    }

    @EpochTransactional(appCode = "cr_b2b_trade_center", dataSourceCode = "cr_ots", dataSourceType = "app")
    public Result<Boolean> cancelOrder() {
        //只有当前状态是待提交时才可以拒绝
        if (!OrderStatus.BEFORE_SUBMIT.getCode().equals(orderSDO.getStatus())) {
            throw new FunctionException("OTS-04-001-00-16-056");
        }
        orderSDO.setStatus(OrderStatus.CANCELLED.getCode());
        orderWriteRepository.updateOrder(this.orderSDO);
        if (CollectionUtils.isNotEmpty(orderSDO.getOrderLineSDOS())) {
            for (OrderLineSDO orderLineSDO : orderSDO.getOrderLineSDOS()) {
                orderLineSDO.setStatus(OrderStatus.CANCELLED.getCode());
                orderLineWriteRepository.modifyOrderLine(orderLineSDO);
            }
        }
        TradeMessageSDO tradeMessageSDO = new TradeMessageSDO();
        tradeMessageSDO.setOrderSDO(orderSDO);
        String message = JSON.toJSONString(tradeMessageSDO);
        Map<String, String> map = new HashMap<>();
        map.put("_CZ_KEY", BcOrderConstants.TENANT_ID());
        messageService.sendMessage("sale_order_message", "CR_SALEORDER_V2", "SaleCanceled", orderSDO.getOrderBizId(), message, map);
        return Result.success(true);
    }

    @FunctionInvoker
    @EpochTransactional(appCode = "cr_b2b_trade_center", dataSourceCode = "cr_ots", dataSourceType = "app")
    public Result<Boolean> modify() {
        log.info("OrderWriteEntity modify orderSDO={}", JSON.toJSONString(orderSDO));

        List<Integer> serialNumberList = new ArrayList<>();
        for (OrderLineSDO orderLineSDO : orderSDO.getOrderLineSDOS()) {
            if (StringUtils.isNotBlank(orderLineSDO.getSerialNumber())) {
                String serialNumber = orderLineSDO.getSerialNumber();
                serialNumberList.add(Integer.parseInt(serialNumber));
            }
        }
        Integer num = 0;
        if (CollectionUtils.isNotEmpty(serialNumberList)) {
            num = serialNumberList.stream().reduce(Integer::max).get() / Integer.parseInt(FIXED_VALUE);
        }

        List<String> ids = new ArrayList<>();
        for (OrderLineSDO orderLineSDO : orderSDO.getOrderLineSDOS()) {
            log.info("OrderWriteEntity modify orderLineSDO={}", JSON.toJSONString(orderLineSDO));
            if (StringUtils.isNotBlank(orderLineSDO.getRefuseReasonCode())) {
                if (isOrderCenterOrder(orderSDO)) {
                    // 订单中心创建的订单，部分交货和已完成推进到已完成、其他状态都推进到已取消
                    if (OrderStatus.PARTIAL_DELIVER.getCode().equals(orderLineSDO.getStatus()) || OrderStatus.COMPLETED.getCode().equals(orderLineSDO.getStatus())) {
                        log.info("OrderWriteEntity modify orderLineSDO setStatus={}", OrderStatus.COMPLETED.getCode());
                        orderLineSDO.setStatus(OrderStatus.COMPLETED.getCode());
                    } else {
                        log.info("OrderWriteEntity modify orderLineSDO setStatus={}", OrderStatus.CANCELLED.getCode());
                        orderLineSDO.setStatus(OrderStatus.CANCELLED.getCode());
                        orderLineSDO.setClosed(GeneralStatusEnum.YES.getCode());
                    }
                } else {
                    // 订单共享创建的订单
                    log.info("OrderWriteEntity modify orderLineSDO setStatus={}", OrderStatus.COMPLETED.getCode());
                    orderLineSDO.setStatus(OrderStatus.COMPLETED.getCode());
                }
                ids.add(orderLineSDO.getId());
            }

            Map<String, String> features = orderLineSDO.getFeatures();
            if (isOrderCenterOrder(orderSDO)) {
                // 打标，修改时方便判断明细行是否为业中订单
                if (Objects.isNull(features)) {
                    features = new HashMap<>();
                }
                features.put("os", "OrderCenter");
                orderLineSDO.setFeatures(features);
            }
            SearchCargoZoneListByDBRequest searchCargoZoneListByDBRequest = new SearchCargoZoneListByDBRequest();
            searchCargoZoneListByDBRequest.setStart(0);
            searchCargoZoneListByDBRequest.setLimit(1);
            searchCargoZoneListByDBRequest.setStatus(1);
            searchCargoZoneListByDBRequest.setCode(orderLineSDO.getShippingWarehouseOutCode());
            searchCargoZoneListByDBRequest.setSapFactoryCode(orderLineSDO.getDeliveryFactoryCode());
            searchCargoZoneListByDBRequest.setWarehouseCode(orderLineSDO.getStockCode());
            SearchCargoZoneListByDBResponse searchCargoZoneListByDBResponse = unifiedInventoryService.searchCargoZoneListByDB(searchCargoZoneListByDBRequest);
            log.info("OrderWriteEntity#modify searchCargoZoneListByDBRequest:{}; searchCargoZoneListByDBResponse:{}", JSON.toJSONString(searchCargoZoneListByDBRequest), JSON.toJSONString(searchCargoZoneListByDBResponse));
            if (searchCargoZoneListByDBResponse.getSuccess()) {
                List<WarehouseInfo> warehouseInfoList = searchCargoZoneListByDBResponse.getResult();
                WarehouseInfo warehouseInfo = warehouseInfoList.get(0);
                if (Objects.nonNull(warehouseInfo) && !Objects.equals(5, warehouseInfo.getType())) {
                    if (SalesOrderStatusEnum.BEFORE_DELIVERY.equals(SalesOrderStatusEnum.of(orderLineSDO.getStatus()))) {
                        if (StringUtils.isBlank(features.get(OrderFeaturesKey.FULFILLMENT_STATUS)) || FulfillmentStatusEnum.FAIL_FULFILLMENT.equals(FulfillmentStatusEnum.of(features.get(OrderFeaturesKey.FULFILLMENT_STATUS)))) {
                            features.put(OrderFeaturesKey.FULFILLMENT_STATUS, FulfillmentStatusEnum.BEFORE_FULFILLMENT.getCode());
                        }
                    } else if (SalesOrderStatusEnum.STAY_PUSH.equals(SalesOrderStatusEnum.of(orderLineSDO.getStatus())) || SalesOrderStatusEnum.PUSHING.equals(SalesOrderStatusEnum.of(orderLineSDO.getStatus()))) {
                        features.put(OrderFeaturesKey.FULFILLMENT_STATUS, FulfillmentStatusEnum.FAIL_FULFILLMENT.getCode());
                    }
                    orderLineSDO.setFeatures(features);
                }
            }
            if (StringUtils.isNotBlank(orderLineSDO.getId())) {
                orderLineWriteRepository.modifyOrderLine(orderLineSDO);
            } else {
                num = ++num * Integer.parseInt(FIXED_VALUE);
                orderLineSDO.setSerialNumber(String.valueOf(num));
                orderLineSDO.setMainOrderId(orderSDO.getId());
                orderLineSDO.setMainOrderBizId(orderSDO.getOrderBizId());
                orderLineSDO.setStatus(OrderStatus.BEFORE_DELIVERY.getCode());
                orderLineSDO.setSyncVersion(0);
                //这里都是修改人创建的
                orderLineSDO.setCreatorName(orderSDO.getModifierName());
                orderLineSDO.setModifierName(orderSDO.getModifierName());
                //设置交货工厂编码
                orderLineSDO.setDeliveryFactoryCode(features.get("factoryCode"));
                //库存地点编码
                orderLineSDO.setStockCode(features.get("inventoryCode"));
                orderLineSDO.setShippingWarehouseCode(orderSDO.getWareHouseCode());
                orderLineSDO.setShippingWarehouseName(orderSDO.getWareHouseName());
                orderLineSDO.setShippingWarehouseOutCode(orderSDO.getWareHouseOutCode());
                orderLineSDO.setSourceLineNum(String.valueOf(num));
                orderLineWriteRepository.save(orderLineSDO);
                num = num / Integer.parseInt(FIXED_VALUE);
            }
        }

        // 订单明细都拒绝时，推进主单状态
        if (CollectionUtils.isNotEmpty(ids) && ids.size() == orderSDO.getOrderLineSDOS().size()) {
            if (isOrderCenterOrder(orderSDO)) {
                // 订单中心创建的订单
                Integer orderStatus = OrderStatus.CANCELLED.getCode();
                for (OrderLineSDO orderLineSDO : orderSDO.getOrderLineSDOS()) {
                    if (OrderStatus.COMPLETED.getCode().equals(orderLineSDO.getStatus())) {
                        // 订单明细只存在已取消和已完成的状态时，设置主单状态为已完成
                        orderStatus = OrderStatus.COMPLETED.getCode();
                        break;
                    }
                }
                orderSDO.setStatus(orderStatus);
            } else {
                // 订单共享创建的订单
                orderSDO.setStatus(OrderStatus.COMPLETED.getCode());
            }
        }
        orderWriteRepository.updateOrder(orderSDO);
        return Result.success(true);
    }

    private boolean isOrderCenterOrder(OrderSDO orderSDO) {
        // os等于OrderCenter时，不更新订单状态
        return !ObjectUtils.isEmpty(orderSDO.getFeatures()) && "OrderCenter".equals(orderSDO.getFeatures().get("os"));
    }

    @Transactional(rollbackFor = RuntimeException.class)
    public String save() {
        orderSDO.setStatus(OrderStatus.BEFORE_SUBMIT.getCode());
        orderSDO.setSyncVersion(0);
        return orderWriteRepository.saveOrder(this.orderSDO);
    }

    /**
     * 修改销售订单状态
     */
    public Boolean modifyStatus() {
        return orderWriteRepository.updateOrderStatus(this.orderSDO);
    }

    /**
     * 备份并删除销售订单
     */
    public void deleteOrder() {
        orderBackUpRepository.deleteOrder(orderSDO);
    }

}
